package com.jhgsys.internal.base.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jhgsys.internal.base.dto.BaseAreDto;
import com.jhgsys.internal.base.dto.BaseAreSchedulingDto;
import com.jhgsys.internal.base.dto.BaseAreaSchedulingDto;
import com.jhgsys.internal.base.dto.BaseAreaSchedulingInfoQuery;
import com.jhgsys.internal.base.entity.BaseArea;
import com.jhgsys.internal.base.service.IBaseAreaService;
import com.jhgsys.internal.common.annotation.Log;
import com.jhgsys.internal.common.controller.BaseController;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.DateUtil;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.base.entity.BaseAreaScheduling;
import com.jhgsys.internal.base.service.IBaseAreaSchedulingService;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 区域排班 Controller
 *
 * @author admin
 * @date 2024-07-31 14:35:45
 */
@Slf4j
@Validated
@Controller
public class BaseAreaSchedulingController extends BaseController {

    @Autowired
    private IBaseAreaSchedulingService baseAreaSchedulingService;

    @Autowired
    private IBaseAreaService baseAreaService;


    @GetMapping(FebsConstant.VIEW_PREFIX + "baseAreaScheduling")
    @RequiresPermissions(value={"baseArea:view"},logical= Logical.OR)
    public String baseAreaSchedulingIndex(Model model){
        model.addAttribute("tenantList", getTenantList());
        model.addAttribute("tenantId", getCurrentTenantId());
        model.addAttribute("hasHeadCompanyRole", hasHeadCompanyRole());
        return FebsUtil.view("base/baseAreaScheduling/baseAreaSchedulingList");
    }

    /**
     * 新增 跳转
     * @param model
     * @param tenantId
     * @return
     */
    @GetMapping(FebsConstant.VIEW_PREFIX + "baseAreaScheduling/add/{tenantId}")
    @RequiresPermissions(value={"baseArea:add"},logical= Logical.OR)
    public String baseAreaSchedulingAdd(Model model, @PathVariable("tenantId") String  tenantId){
        BaseArea queryArea = new BaseArea();
        queryArea.setTenantId(tenantId);
        List<BaseArea> areaList = baseAreaService.findBaseAreaList(queryArea);
        model.addAttribute("areaList",areaList);
        return FebsUtil.view("base/baseAreaScheduling/baseAreaSchedulingEdit");
    }

    /**
     * 更新跳转
     * @param model
     * @param id
     * @return
     */
    @GetMapping(FebsConstant.VIEW_PREFIX + "baseAreaScheduling/update/{areaId}/{startDate}/{endDate}")
    @RequiresPermissions(value={"baseArea:edit"},logical= Logical.OR)
    public String baseAreaSchedulingUpdate(Model model, @PathVariable("areaId") String areaId,@PathVariable("startDate") String startDate,@PathVariable("endDate") String endDate){
        BaseArea baseArea=baseAreaService.findBaseAreaById(areaId);
        model.addAttribute("baseArea",baseArea);
        BaseAreaSchedulingDto query = new BaseAreaSchedulingDto();
        query.setAreaId(areaId);
        query.setStartDate(startDate);
        query.setEndDate(endDate);
        List<BaseAreaSchedulingDto> dtoList = baseAreaSchedulingService.findBaseAreaSchedulingList(query);
        model.addAttribute("baseAreaScheduling", dtoList);
        model.addAttribute("areaList", Collections.singletonList(baseArea));

        return FebsUtil.view("base/baseAreaScheduling/baseAreaSchedulingEdit");
    }


    /**
     * 排班信息获取动态表头
     * @param request 分页信息
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param areaName 区域名称
     * @param tenantId 租户ID
     * @return
     */
    @GetMapping("baseAreaScheduling/getDate")
    @ResponseBody
    @RequiresPermissions(value={"baseArea:view"},logical= Logical.OR)
    public FebsResponse getDate(QueryRequest request,
                                               @RequestParam(name = "startDate",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                               @RequestParam(name = "endDate",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
                                               @RequestParam(name = "areaName",required = false) String areaName,
                                               @RequestParam(name = "tenantId",required = true) String tenantId) {
        BaseAreaSchedulingInfoQuery query = new BaseAreaSchedulingInfoQuery();
        if(startDate == null && endDate==null){
            query.setStartDate(DateUtil.getPastDate(DateUtil.getCurrentDay(),-7));
            query.setEndtDate(DateUtil.getPastDate(DateUtil.getCurrentDay(),7));
        } else if(startDate == null && endDate != null){
            query.setStartDate(DateUtil.getPastDate(DateUtil.getCurrentDay(),-7));
            query.setEndtDate(endDate);
        } else if(startDate != null && endDate == null){
            query.setStartDate(startDate);
            query.setEndtDate(DateUtil.getPastDate(DateUtil.getCurrentDay(),7));
        } else {
            query.setStartDate(startDate);
            query.setEndtDate(endDate);
        }
        query.setTenantId(tenantId);
        List<String> dateList = this.baseAreaSchedulingService.selectDate(query);
        if(!CollectionUtils.isEmpty(dateList)){
            log.info("获取到的表头：{}",JSON.toJSONString(dateList));
            return new FebsResponse().success().data(dateList);
        }else {
            return new FebsResponse().success().data(new ArrayList<String>());
        }
    }
    /**
     * 排班总览查询（分页）
     * @author admin
     * @date 2024-07-31 14:35:45
     */
    @GetMapping("baseAreaScheduling/list")
    @ResponseBody
    @RequiresPermissions(value={"baseArea:view"},logical= Logical.OR)
    public FebsResponse baseAreaSchedulingList(QueryRequest request,
                                               @RequestParam(name = "startDate",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                               @RequestParam(name = "endDate",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
                                               @RequestParam(name = "areaId",required = false) String areaId,
                                               @RequestParam(name = "tenantId",required = true) String tenantId) {
        //设置查询条件
        BaseAreDto baseArea = new BaseAreDto();
        if(StringUtils.isNotBlank(areaId)){
            baseArea.setAreaId(areaId);
        }
        if(StringUtils.isNotBlank(tenantId)){
            baseArea.setTenantId(tenantId);
        }
        baseArea.setStatus("1");
        IPage<Map<String, Object>> resultPage = baseAreaService.findbaseAreaSchedulingInfoPage(request,baseArea,startDate,endDate);
        log.info("最终排班信息1:{}",JSON.toJSONString(resultPage));
        Map<String, Object> dataTable = getDataTable(resultPage);
        return new FebsResponse().success().data(dataTable);
    }



    /**
     * 新增 区域排班
     * @author admin
     * @date 2024-07-31 14:35:45
     */
    @Log("新增区域排班")
    @PostMapping("baseAreaScheduling")
    @ResponseBody
    @RequiresPermissions(value={"baseArea:add"},logical= Logical.OR)
    public FebsResponse addBaseAreaScheduling(@RequestBody BaseAreSchedulingDto baseAreSchedulingDto) {
        try {
            if(StringUtils.isBlank(baseAreSchedulingDto.getAreaId())){
                return new FebsResponse().fail().message("区域不能为空");
            }
            if(CollectionUtils.isEmpty(baseAreSchedulingDto.getSchedulingList())){
                return new FebsResponse().fail().message("排班人员信息不能为空不能为空");
            }
            List<BaseAreaScheduling> list = baseAreSchedulingDto.getSchedulingList();

            Set<Date> schedulingDate = list.stream().map(BaseAreaScheduling::getSchedulingDate).collect(Collectors.toSet());


            StringBuilder existDate = new StringBuilder();
            schedulingDate.forEach(item ->{
                List<BaseAreaScheduling> schedulingList = this.baseAreaSchedulingService.list(new LambdaUpdateWrapper<BaseAreaScheduling>()
                        .eq(BaseAreaScheduling::getDeletedFlg,FebsConstant.VALID)
                        .eq(BaseAreaScheduling::getAreaId,baseAreSchedulingDto.getAreaId())
                        .eq(BaseAreaScheduling::getSchedulingDate,item));
                if(!CollectionUtils.isEmpty(schedulingList)){
                    String date = DateUtil.getDateFormat(item,DateUtil.YYYY_MM_DD_PATTERN);
                    existDate.append(date).append(",");
                }
            });
            /*if(StringUtils.isNotBlank(existDate.toString())){
                return new FebsResponse().fail().message("该区域【"+existDate.deleteCharAt(existDate.length()-1)+"】排班已存在");
            }*/
            list.forEach(item->{
                item.setAreaId(baseAreSchedulingDto.getAreaId());
                item.setCreatedTime(new Date());
                item.setCreatedBy(getCurrentUser().getUserName());
                item.setDeletedFlg(FebsConstant.VALID);
                item.setTenantId(baseAreSchedulingDto.getTenantId());
            });

            this.baseAreaSchedulingService.saveBatch(list);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "新增区域排班信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
     * 逻辑删除 区域排班信息
     * @author admin
     * @date 2024-07-31 14:35:45
     */
    @Log("逻辑删除区域排班信息")
    @GetMapping("baseAreaScheduling/delete/{id}")
    @ResponseBody
    @RequiresPermissions(value={"baseArea:delete"},logical= Logical.OR)
    public FebsResponse deleteBaseAreaScheduling(@PathVariable("id") String baseAreaSchedulingIds) {
        try {
            BaseAreaScheduling baseAreaScheduling = new BaseAreaScheduling();
            baseAreaScheduling.setDeletedBy(getCurrentUser().getUserName());
            baseAreaScheduling.setDeletedTime(new Date());
            baseAreaScheduling.setDeletedFlg(FebsConstant.INVALID);
            this.baseAreaSchedulingService.deleteBaseAreaScheduling(baseAreaScheduling,baseAreaSchedulingIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "删除区域排班信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }



    /**
     * 修改 区域排班信息
     * @author admin
     * @date 2024-07-31 14:35:45
     */
    @Log("修改区域排班信息")
    @PostMapping("baseAreaScheduling/update")
    @ResponseBody
    @RequiresPermissions(value={"baseArea:edit"},logical= Logical.OR)
    public FebsResponse updateBaseAreaScheduling(@RequestBody BaseAreSchedulingDto baseAreSchedulingDto) {
        try {
            List<BaseAreaScheduling> schedulingList = baseAreSchedulingDto.getSchedulingList();
            Date scDate = schedulingList.get(0).getSchedulingDate();
            //将该区域原排班信息更改为失效
            this.baseAreaSchedulingService.update(new LambdaUpdateWrapper<BaseAreaScheduling>()
                    .eq(BaseAreaScheduling::getDeletedFlg,FebsConstant.VALID)
                    .eq(BaseAreaScheduling::getAreaId,baseAreSchedulingDto.getAreaId())
                    .ge(BaseAreaScheduling::getSchedulingDate,scDate)
                    .set(BaseAreaScheduling::getDeletedFlg,FebsConstant.INVALID)
                    .set(BaseAreaScheduling::getUpdatedBy,getCurrentUser().getUserName())
                    .set(BaseAreaScheduling::getUpdatedTime,new Date()));
            //批量新增新的排班信息
            schedulingList.forEach(item->{
                item.setAreaId(baseAreSchedulingDto.getAreaId());
                item.setCreatedTime(new Date());
                item.setCreatedBy(getCurrentUser().getUserName());
                item.setUpdatedBy(getCurrentUser().getUserName());
                item.setUpdatedTime(new Date());
                item.setDeletedFlg(FebsConstant.VALID);
                item.setTenantId(baseAreSchedulingDto.getTenantId());
            });
            this.baseAreaSchedulingService.saveOrUpdateBatch(schedulingList);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "修改区域排班信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
     * 导出区域排班信息的excel
     * @author admin
     * @date 2024-07-31 14:35:45
     */
    @PostMapping("baseAreaScheduling/excel")
    @ResponseBody
    @RequiresPermissions("baseAreaScheduling:view")
    public void export(QueryRequest queryRequest, BaseAreaScheduling baseAreaScheduling, HttpServletResponse response) throws FebsException {
        try {
            List<BaseAreaScheduling> baseAreaSchedulings = this.baseAreaSchedulingService.findBaseAreaSchedulingPage(queryRequest, baseAreaScheduling).getRecords();
            ExcelKit.$Export(BaseAreaScheduling.class, response).downXlsx(baseAreaSchedulings, false);
        } catch (Exception e) {
            String message = "导出Excel失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }
}
